package routers

import (
	"context"
	"encoding/json"
	"fmt"
	"math"
	"net/http"
	"net/rpc"
	"strconv"
	"time"

	"gorm.io/gorm"
	"shqsoft.cn/pas3ui/base"
	"shqsoft.cn/pas3ui/entity"

	//log "github.com/cihub/seelog"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo"
)

var ctx = context.Background()

//对公账户认定
func AccountDiviRouter(c echo.Context) error {
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(*UserLoginClaims)
	userid := strconv.Itoa(claims.UserID)
	var userNo string
	err := base.MYDB.Raw(`select "SysUserID" from "T_SysUser" where "ID"=?`, userid).Row().Scan(&userNo)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	var acids []int
	jsonStr := c.FormValue("Acids")
	if jsonStr == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "Acids不能为空！")
	}
	err = json.Unmarshal([]byte(jsonStr), &acids)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	if l := len(acids); l == 0 {
		return echo.NewHTTPError(http.StatusBadRequest, "Acids不能为空数组！")
	}
	jsonStr = c.FormValue("DiviMap")
	if jsonStr == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "DataSource不能为空！")
	}
	var diviMap map[int]float64
	err = json.Unmarshal([]byte(jsonStr), &diviMap)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	if l := len(diviMap); l == 0 {
		return echo.NewHTTPError(http.StatusBadRequest, "DiviMap不能为空数组！")
	}
	dsdtStr := c.FormValue("Dsdt")
	if dsdtStr == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "Dsdt不能为空！")
	}
	dsdt, err := time.Parse("2006-01-02", dsdtStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "Dsdt不是有效的日期！")
	}
	bdate, err := base.GetBackDATE()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	if dsdt.Unix() < bdate.Unix() {
		return echo.NewHTTPError(http.StatusBadRequest, "分户日期不能小于最早可追溯日期，最大追溯日期为【"+bdate.Format("2006-01-02")+"】")
	}
	name := c.Param("Name")
	if name == "Comp" {
		err = entity.CompDiviBatchSave(acids, &dsdt, userNo, diviMap)
	} else if name == "CmBizFee" {
		err = entity.CmBizFeeDiviBatchSave(acids, userNo, diviMap)
	} else if name == "Indi" {
		err = entity.IndiDiviBatchSave(acids, &dsdt, userNo, diviMap)
	} else if name == "IndiLoan" {
		err = entity.IndiLoanDiviBatchSave(acids, &dsdt, userNo, diviMap)
	}
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.String(http.StatusOK, "OK")
}

//UserOrganUpdateRouter 保存业绩转移方式，提交流程，更新营销关系
func UserOrganUpdateRouter(c echo.Context) error {
	YGid := c.FormValue("ID")
	YJBD := c.FormValue("YJBD")
	var emid1 *int
	var emid2 *int
	zb1 := 0.0
	zb2 := 0.0
	var err error
	if YJBD == "2" {
		strEMID := c.FormValue("NEMID1")
		if strEMID != "" {
			id1, err := strconv.Atoi(strEMID)
			if err != nil {
				return echo.NewHTTPError(http.StatusBadRequest, err.Error())
			}
			emid1 = &id1
		}
		strEMID2 := c.FormValue("NEMID2")
		if strEMID2 != "" {
			id2, err := strconv.Atoi(strEMID2)
			if err != nil {
				return echo.NewHTTPError(http.StatusBadRequest, err.Error())
			}
			emid2 = &id2
		}
		zb1, err = strconv.ParseFloat(c.FormValue("ZB1"), 64)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
		zb2, err = strconv.ParseFloat(c.FormValue("ZB2"), 64)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	if YJBD == "2" && math.Abs(zb1+zb2-100) > 0.01 {
		return echo.NewHTTPError(http.StatusBadRequest, "占比之和必须为100")
	}
	var userNewOrgan entity.UserNewOrgan
	err = base.MYDB.Where(`"ID" = ?`, YGid).Find(&userNewOrgan).Error
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	tx := base.MYDB.Begin()
	tx.Exec(`UPDATE "T_SysUser_YGDD" SET "YJBD"=?,"NEWEMID"=?,"ZB1"=?,"NEWEMID2"=?,"ZB2"=?,"ISCL"=1 WHERE "ID"= ? `, YJBD, emid1, zb1, emid2, zb2, YGid)
	//更新处理业绩调整存储过程
	if YJBD == "2" {
		pemid1 := 0
		pemid2 := 0
		if emid1 != nil {
			pemid1 = *emid1
		}
		if emid2 != nil {
			pemid2 = *emid2
		}
		err = userNewOrganDivi(tx, userNewOrgan, pemid1, pemid2, zb1, zb2)
		if err != nil {
			return err
		}
	}
	err = tx.Exec(`UPDATE "T_SysUser" SET "OrganID"=? WHERE "ID"=?`, userNewOrgan.NUTID, userNewOrgan.EMID).Error
	if err != nil {
		return err
	}
	tx.Commit()
	return c.JSON(http.StatusOK, "OK")
}

func userNewOrganDivi(tx *gorm.DB, userNewOrgan entity.UserNewOrgan, emid1, emid2 int, zb1, zb2 float64) error {
	eng := "ENGINE=MEMORY DEFAULT CHARSET=utf8"
	if base.AppConf.Database.Mysql == "" || base.AppConf.Database.Pgsql == "" {
		eng = ""
	}
	// 插入对公业绩转移(未终止)
	sqlstr := fmt.Sprintf(`CREATE TABLE "TMP_DIVI_DG"(
		"ACID" int,
		"DSTY" int,
		"EMID" int,
		"DSVL" float,
		"DSDT" date,
		"DSEM" varchar(20),
		"WODT" date,
		"WOEM" varchar(20),
		"ISWO" int
	)%s`, eng)
	err := tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	if emid1 > 0 && zb1 > 0 {
		sqlstr := `INSERT INTO "TMP_DIVI_DG"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","WODT","WOEM","ISWO")
		SELECT "ACID","DSTY",? "EMID","DSVL"/100*? "DSVL",CASE WHEN "DSDT"<? THEN ? ELSE "DSDT" END "DSDT",'YGDD' "DSEM","WODT","WOEM","ISWO"
		FROM "T_COMP_ACCO_DIVI" 
		WHERE "EMID"=? AND "ISWO"=0 AND ("WODT" IS NULL OR "WODT">?)`
		err = tx.Exec(sqlstr, emid1, zb1, userNewOrgan.DDDT, userNewOrgan.DDDT, userNewOrgan.EMID, userNewOrgan.DDDT).Error
		if err != nil {
			return err
		}
	}
	if emid2 > 0 && zb2 > 0 {
		sqlstr := `INSERT INTO "TMP_DIVI_DG"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","WODT","WOEM","ISWO")
		SELECT "ACID","DSTY",? "EMID","DSVL"/100*? "DSVL",CASE WHEN "DSDT"<? THEN ? ELSE "DSDT" END "DSDT",'YGDD' "DSEM","WODT","WOEM","ISWO"
		FROM "T_COMP_ACCO_DIVI" 
		WHERE "EMID"=? AND "ISWO"=0 AND ("WODT" IS NULL OR "WODT">?)`
		err = tx.Exec(sqlstr, emid2, zb2, userNewOrgan.DDDT, userNewOrgan.DDDT, userNewOrgan.EMID, userNewOrgan.DDDT).Error
		if err != nil {
			return err
		}
	}
	// 终止对公业绩
	sqlstr = `UPDATE "T_COMP_ACCO_DIVI" SET "WODT"=?,"WOEM"='YGDD',"ISWO"=CASE WHEN "DSDT"<? THEN 0 ELSE 1 END
	WHERE "EMID"=? AND "ISWO"=0 AND ("WODT" IS NULL OR "WODT">?)`
	err = tx.Exec(sqlstr, userNewOrgan.DDDT, userNewOrgan.DDDT, userNewOrgan.EMID, userNewOrgan.DDDT).Error
	if err != nil {
		return err
	}
	// 插入认定
	sqlstr = `INSERT INTO "T_COMP_ACCO_DIVI"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","WODT","WOEM","ISWO")
	SELECT "ACID","DSTY","EMID","DSVL",CASE WHEN "DSDT"<? THEN ? ELSE "DSDT" END,"DSEM","WODT","WOEM","ISWO"
	FROM "TMP_DIVI_DG"
	WHERE "DSDT"<"WODT" OR "WODT" IS NULL`
	err = tx.Exec(sqlstr, userNewOrgan.DDDT, userNewOrgan.DDDT).Error
	if err != nil {
		return err
	}
	sqlstr = `DROP TABLE "TMP_DIVI_DG"`
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	// 插入储蓄业绩转移(未终止)
	sqlstr = fmt.Sprintf(`CREATE TABLE "TMP_DIVI_LS"(
		"ACID" int,
		"DSTY" int,
		"EMID" int,
		"DSVL" float,
		"DSDT" date,
		"DSEM" varchar(20),
		"WODT" date,
		"WOEM" varchar(20),
		"ISWO" int
	)%s`, eng)
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	if emid1 > 0 && zb1 > 0 {
		sqlstr = `INSERT INTO "TMP_DIVI_LS"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","WODT","WOEM","ISWO")
		SELECT "ACID","DSTY",? "EMID","DSVL"/100*? "DSVL",CASE WHEN "DSDT"<? THEN ? ELSE "DSDT" END "DSDT",'YGDD' "DSEM","WODT","WOEM","ISWO"
		FROM "T_INDI_ACCO_DIVI" 
		WHERE "EMID"=? AND "ISWO"=0 AND ("WODT" IS NULL OR "WODT">?)`
		err = tx.Exec(sqlstr, emid1, zb1, userNewOrgan.DDDT, userNewOrgan.DDDT, userNewOrgan.EMID, userNewOrgan.DDDT).Error
		if err != nil {
			return err
		}
	}
	if emid2 > 0 && zb2 > 0 {
		sqlstr = `INSERT INTO "TMP_DIVI_LS"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","WODT","WOEM","ISWO")
		SELECT "ACID","DSTY",? "EMID","DSVL"/100*? "DSVL",CASE WHEN "DSDT"<? THEN ? ELSE "DSDT" END "DSDT",'YGDD' "DSEM","WODT","WOEM","ISWO"
		FROM "T_INDI_ACCO_DIVI" 
		WHERE "EMID"=? AND "ISWO"=0 AND ("WODT" IS NULL OR "WODT">?)`
		err = tx.Exec(sqlstr, emid2, zb2, userNewOrgan.DDDT, userNewOrgan.DDDT, userNewOrgan.EMID, userNewOrgan.DDDT).Error
		if err != nil {
			return err
		}
	}
	// 终止对私业绩
	sqlstr = `UPDATE "T_INDI_ACCO_DIVI" SET "WODT"=?,"WOEM"='YGDD',"ISWO"=CASE WHEN "DSDT"<? THEN 0 ELSE 1 END
	WHERE "EMID"=? AND "ISWO"=0 AND ("WODT" IS NULL OR "WODT">?)`
	err = tx.Exec(sqlstr, userNewOrgan.DDDT, userNewOrgan.DDDT, userNewOrgan.EMID, userNewOrgan.DDDT).Error
	if err != nil {
		return err
	}
	// 插入认定
	sqlstr = `INSERT INTO "T_INDI_ACCO_DIVI"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","WODT","WOEM","ISWO")
	SELECT "ACID","DSTY","EMID","DSVL",CASE WHEN "DSDT"<? THEN ? ELSE "DSDT" END,"DSEM","WODT","WOEM","ISWO"
	FROM "TMP_DIVI_LS"
	WHERE "DSDT"<"WODT" OR "WODT" IS NULL`
	err = tx.Exec(sqlstr, userNewOrgan.DDDT, userNewOrgan.DDDT).Error
	if err != nil {
		return err
	}
	sqlstr = `DROP TABLE "TMP_DIVI_LS"`
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	// 插入个贷业绩转移(未终止)
	sqlstr = fmt.Sprintf(`CREATE TABLE "TMP_DIVI_GD"(
		"ACID" int,
		"DSTY" int,
		"EMID" int,
		"DSVL" float,
		"DSDT" date,
		"DSEM" varchar(20),
		"WODT" date,
		"WOEM" varchar(20),
		"ISWO" int
	)%s`, eng)
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	if emid1 > 0 && zb1 > 0 {
		sqlstr = `INSERT INTO "TMP_DIVI_GD"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","WODT","WOEM","ISWO")
		SELECT "ACID","DSTY",? "EMID","DSVL"/100*? "DSVL",CASE WHEN "DSDT"<? THEN ? ELSE "DSDT" END "DSDT",'YGDD' "DSEM","WODT","WOEM","ISWO"
		FROM "T_INDI_LOAN_DIVI" 
		WHERE "EMID"=? AND "ISWO"=0 AND ("WODT" IS NULL OR "WODT">?)`
		err = tx.Exec(sqlstr, emid1, zb1, userNewOrgan.DDDT, userNewOrgan.DDDT, userNewOrgan.EMID, userNewOrgan.DDDT).Error
		if err != nil {
			return err
		}
	}
	if emid2 > 0 && zb2 > 0 {
		sqlstr = `INSERT INTO "TMP_DIVI_GD"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","WODT","WOEM","ISWO")
		SELECT "ACID","DSTY",? "EMID","DSVL"/100*? "DSVL",CASE WHEN "DSDT"<? THEN ? ELSE "DSDT" END "DSDT",'YGDD' "DSEM","WODT","WOEM","ISWO"
		FROM "T_INDI_LOAN_DIVI" 
		WHERE "EMID"=? AND "ISWO"=0 AND ("WODT" IS NULL OR "WODT">?)`
		err = tx.Exec(sqlstr, emid2, zb2, userNewOrgan.DDDT, userNewOrgan.DDDT, userNewOrgan.EMID, userNewOrgan.DDDT).Error
		if err != nil {
			return err
		}
	}
	// 终止个贷业绩
	sqlstr = `UPDATE "T_INDI_LOAN_DIVI" SET "WODT"=?,"WOEM"='YGDD',"ISWO"=CASE WHEN "DSDT"<? THEN 0 ELSE 1 END
	WHERE "EMID"=? AND "ISWO"=0 AND ("WODT" IS NULL OR "WODT">?)`
	err = tx.Exec(sqlstr, userNewOrgan.DDDT, userNewOrgan.DDDT, userNewOrgan.EMID, userNewOrgan.DDDT).Error
	if err != nil {
		return err
	}
	// 插入个贷认定
	sqlstr = `INSERT INTO "T_INDI_LOAN_DIVI"("ACID","DSTY","EMID","DSVL","DSDT","DSEM","WODT","WOEM","ISWO")
	SELECT "ACID","DSTY","EMID","DSVL",CASE WHEN "DSDT"<? THEN ? ELSE "DSDT" END,"DSEM","WODT","WOEM","ISWO"
	FROM "TMP_DIVI_GD"
	WHERE "DSDT"<"WODT" OR "WODT" IS NULL`
	err = tx.Exec(sqlstr, userNewOrgan.DDDT, userNewOrgan.DDDT).Error
	if err != nil {
		return err
	}
	sqlstr = `DROP TABLE "TMP_DIVI_GD"`
	err = tx.Exec(sqlstr).Error
	if err != nil {
		return err
	}
	return nil
}

//UpdateZSRQRouter 设置追溯日期路由
func UpdateZSRQRouter(c echo.Context) (err error) {
	day := c.FormValue("day")
	var (
		compTmst time.Time
		cmbiTmst time.Time
		indiTmst time.Time
		loanTmst time.Time
		updtTmst time.Time
		res      string
	)
	tx := base.MYDB
	sqlStr := `SELECT MAX("TMST") FROM "T_COMP_ACCO_DIVI"`
	err = tx.Raw(sqlStr).Row().Scan(&compTmst)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	sqlStr = `SELECT MAX("TMST") FROM "T_CM_BIZ_FEE_DIVI"`
	err = tx.Raw(sqlStr).Row().Scan(&cmbiTmst)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	sqlStr = `SELECT MAX("TMST") FROM "T_INDI_ACCO_DIVI"`
	err = tx.Raw(sqlStr).Row().Scan(&indiTmst)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	sqlStr = `SELECT MAX("TMST") FROM "T_INDI_LOAN_DIVI"`
	err = tx.Raw(sqlStr).Row().Scan(&loanTmst)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	sqlStr = `SELECT "TMST" FROM "T_CONF_UPDT"`
	err = tx.Raw(sqlStr).Row().Scan(&updtTmst)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	if compTmst.Unix() > updtTmst.Unix() || cmbiTmst.Unix() > updtTmst.Unix() || indiTmst.Unix() > updtTmst.Unix() || loanTmst.Unix() > updtTmst.Unix() {
		res = "有新认定的客户未处理完！"
	} else {
		res = "OK"
		err = base.MYDB.Exec(`UPDATE "T_CONF_UPDT" SET "BDAY"=?`, day).Error
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	return c.JSON(http.StatusOK, res)
}

//DefaultDateRouter 获取追溯日期路由
func DefaultDateRouter(c echo.Context) (err error) {
	var date string
	odsdate, err := base.GetBackDATE()
	if err != nil {
		return err
	}
	date = odsdate.Format("2006-01-02")
	return c.JSON(http.StatusOK, date)
}

//DataProcessRouter 数据处理路由
func DataProcessRouter(c echo.Context) (err error) {
	var dateString string
	var date time.Time
	var isOK *int
	jsonStr := c.FormValue("Date")
	err = json.Unmarshal([]byte(jsonStr), &dateString)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	date, _ = time.Parse("2006-01-02", dateString)
	conn, err := rpc.DialHTTP("tcp", base.AppConf.Rpc.Tcp)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	err = conn.Call("DataProc.DataProcess", &date, &isOK)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.String(http.StatusOK, "OK")
}

func ygddFsChangeRouter(c echo.Context) (err error) {
	frid, err := strconv.Atoi(c.Param("frid"))
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "员工调动创建调动账户出错,路径参数frid不是有效的整数")
	}
	ywlx, err := strconv.Atoi(c.FormValue("ywlx"))
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "员工调动创建调动账户出错,form参数ywlx不是有效的整数")
	}
	yjbd, err := strconv.Atoi(c.FormValue("yjbd"))
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "员工调动创建调动账户出错,form参数yjbd不是有效的整数")
	}
	islz, err := strconv.ParseBool(c.FormValue("islz"))
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "员工调动创建调动账户出错,form参数islz不是有效的bool")
	}
	if islz {
		err = entity.YglzFsChange(frid, ywlx, yjbd)
	} else {
		err = entity.YgddFsChange(frid, ywlx, yjbd)
	}
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "员工调动创建调动账户出错:"+err.Error())
	}
	return c.String(http.StatusOK, "OK")
}
